﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    //工厂方法对每一个类创建一个工厂，用来封装类复杂的构造、实例化、初始化过程。一个工厂负责一个产品的生产，实现了以上的目的。
    //但是当需要生产的产品类型比较多时，就会建立各种各样的工厂，造成工厂泛滥。
    //为了避免工厂泛滥，我们一个工厂生产一个族的产品，而使用制造方法的划分生产不同系列的产品。
    //以汽车场为例，A厂只生产A品牌的汽车，B厂只生产B品牌的汽车，C厂生产C品牌的汽车。A、B、C工厂都可以生产轿车类型、越野类型、跑车类型的汽车。
    //这时候面对三种不同厂家的三种不同类型的汽车时，我们不能使用工厂模式一样新建9个工厂，这会导致工厂泛滥，而且维护性和可扩展性不好。
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        #region 产品分类
        public abstract class Car
        {
            /// <summary>
            /// 马力
            /// </summary>
            public int HorsePower { set; get; }

            /// <summary>
            /// 油耗
            /// </summary>
            public int FuelConsumption { set; get; }
            /// <summary>
            /// 空间
            /// </summary>
            public int Size { set; get; }

            public Car(int horsepower,int fuelConsumption,int size)
            {
                this.HorsePower = horsepower;
                this.FuelConsumption = fuelConsumption;
                this.Size = size;
            }

            /// <summary>
            /// 运行
            /// </summary>
            public abstract void Run();
            /// <summary>
            /// 刹车
            /// </summary>
            public abstract void Break();

        }
        /// <summary>
        /// 豪华轿车(空间大，马力油耗相对较低)
        /// </summary>
        public abstract class Limousine : Car
        {
            public Limousine():base( 6,  6,  10)
            {

            }
        
        }
        /// <summary>
        /// 越野车(空间偏大，马力偏大，油耗高)
        /// </summary>
        public abstract class CrossCountry : Car
        {
            public CrossCountry() : base(8, 10, 8)
            {

            }

        }
        /// <summary>
        /// 跑车(马力大，油耗偏大，空间小)
        /// </summary>
        public abstract class Sports:Car
        {
            public Sports() : base(10, 8, 3)
            {

            }
        }
        #endregion

        #region 工厂抽象
        public abstract class AbstractFactory
        {
            /// <summary>
            /// 生产轿车
            /// </summary>
            /// <returns></returns>
            public abstract Limousine ManufactureLimosine();
            /// <summary>
            /// 生产越野车
            /// </summary>
            /// <returns></returns>
            public abstract CrossCountry ManufactureCrossCountry();
            /// <summary>
            /// 生产跑车
            /// </summary>
            /// <returns></returns>
            public abstract Sports ManufactureSports();

        }
        #endregion

        #region 产品
        #region A厂产品
        public class LimousineA : Limousine
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }

        public class CrossCountryA : CrossCountry
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }

        public class SportsA : Sports
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }

        #endregion

        #region B厂产品
        public class LimousineB : Limousine
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }

        public class CrossCountryB : CrossCountry
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }

        public class SportsB : Sports
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }
        #endregion

        #region C厂产品
        public class LimousineC : Limousine
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }

        public class CrossCountryC : CrossCountry
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }

        public class SportsC : Sports
        {
            public override void Break()
            {
                throw new NotImplementedException();
            }

            public override void Run()
            {
                throw new NotImplementedException();
            }
        }
        #endregion
        #endregion

        #region 工厂

        #region 工厂A
        public class FactoryA : AbstractFactory
        {
            public override CrossCountry ManufactureCrossCountry()
            {
                return new CrossCountryA();
            }

            public override Limousine ManufactureLimosine()
            {
                return new LimousineA();
            }

            public override Sports ManufactureSports()
            {
                return new SportsA();
            }
        }
        #endregion

        #region 工厂B
        public class FactoryB : AbstractFactory
        {
            public override CrossCountry ManufactureCrossCountry()
            {
                return new CrossCountryB();
            }

            public override Limousine ManufactureLimosine()
            {
                return new LimousineB();
            }

            public override Sports ManufactureSports()
            {
                return new SportsC();
            }
        }
        #endregion

        #region 工厂C
        public class FactoryC : AbstractFactory
        {
            public override CrossCountry ManufactureCrossCountry()
            {
                return new CrossCountryA();
            }

            public override Limousine ManufactureLimosine()
            {
                return new LimousineB();
            }

            public override Sports ManufactureSports()
            {
                return new SportsC();
            }
        }
        #endregion

        #endregion

        //TODO 可以再添加一个制造工厂的工厂。大道至简，灵活变通
        private void button1_Click(object sender, EventArgs e)
        {
            //创建工厂
            FactoryA factoryA = new FactoryA();
            FactoryB factoryB = new FactoryB();
            FactoryC factoryC = new FactoryC();

            //生产产品
            CrossCountryA crossCountryA =(CrossCountryA)factoryA.ManufactureCrossCountry();
            CrossCountryB crossCountryB = (CrossCountryB)factoryB.ManufactureCrossCountry();
            CrossCountryC crossCountryC = (CrossCountryC)factoryC.ManufactureCrossCountry();

            LimousineA limousineA = (LimousineA)factoryA.ManufactureLimosine();
            LimousineB limousineB = (LimousineB)factoryB.ManufactureLimosine();
            LimousineC limousineC = (LimousineC)factoryC.ManufactureLimosine();

            SportsA sportsA = (SportsA)factoryA.ManufactureSports();
            SportsB sportsB = (SportsB)factoryB.ManufactureSports();
            SportsC sportsC = (SportsC)factoryC.ManufactureSports();
        }
    }
}
